# ESP32 Smart Robot Arm
**Read Me First**
1. Please download all the files needed to run the robot arm, including the driver, codes, libraries, etc: https://fs.keyestudio.com/FKS0003
2. Technical Support: service@keyestudio.com
3. What do you need to prepare:
- Six AA batteries or two 18650 batteries
- A computer with a stable Internet connection
- We can use the joystick to control the robot arm. But if you want to control it wirelessly, you need to prepare a ***\*2.4 GHz\**** WiFi(It can be a mobile hotspot or a router)
## 1. Kit List
**Please check the list to ensure that all parts are intact. If you find missing ones, please contact our sales staff immediately.**
| # | PIC | NAME | QTY |
| :--: | :-------------------------------------------------------: | :----------------------------------------------------------: | :--: |
| 1 |  | Keyestudio ESP32 servo drive board | 1 |
| 2 |  | keyestudio ESP32 Core board | 1 |
| 3 |  | Keyestudio Joystick Module | 2 |
| 4 |  | 3D PS2 joystick cap | 2 |
| 5 |  | Acrylic handle T=3MM | 1 |
| 6 |  | MG90S 14G 180° metal servo | 3 |
| 7 |  | 9G 180° servo for robot claw | 1 |
| 8 |  | DC 6-slot AA battery holder 15CM connector | 1 |
| 9 |  | 2 18650 battery packs
(recommended to use pointed 18650 batteries) | 1 |
| 10 |  | F-F 50CM/10P DuPont wire | 1 |
| 11 |  | cable tie 3*100MM | 7 |
| 12 |  | Micro USB cable | 1 |
| 13 |  | 3 pin M-F 20CM DuPont wire (used to extend the wire of the clip) | 1 |
| 14 |  | 3*40MM Phillips screwdriver | 1 |
| 15 |  | M2+M3 wrench | 1 |
| 16 |  | F693ZZ motor class
Inner: 3MM; Outer: 8MM; Thickness: 4MM | 3 |
| 17 |  | AXK 3-plate flat bearing
Inner: 20MM; Outer: 35MM, Thickness: 4MM | 1 |
| 18 |  | 2 bearing covers(You need to tear off the brown protective film) | 1 |
| 19 |  | 4 acrylic board | 1 |
| 20 |  | M3 nut | 14 |
| 21 |  | M2 nut | 4 |
| 22 |  | M3 self-locking nut | 8 |
| 23 |  | M2.5 nut | 8 |
| 24 |  | M3*6MM round head screw | 4 |
| 25 |  | M2*10MM round head screw | 4 |
| 26 |  | M3*8MM round head screw | 4 |
| 27 |  | M1.2*5MM self-tapping screw 2.54MM | 2 |
| 28 |  | M3*10MM round head screw | 3 |
| 29 |  | M3*12MM round head screw | 5 |
| 30 |  | M3*6MM round head nylon screw | 8 |
| 31 |  | M3*16mm dual-pass nylon pillar | 2 |
| 32 |  | M3*22mm dual-pass nylon pillar | 2 |
| 33 |  | M2*8MM self-tapping screw | 4 |
| 34 |  | M1.2*4MM self-tapping screw 2.54MM | 4 |
| 35 |  | M3*8MM flat head screw | 2 |
| 36 |  | M2.5*25+6MM single-pass copper pillar | 8 |
| 37 |  | M2.5*6MM round head screw | 8 |
| 38 |  | M1.4x6MM self-tapping screw or
M1.4x8MM self-tapping screw | 4 |
| 39 |  | M3*6+6MM single-pass copper pillar | 6 |
| 40 |  | M3*14MM flat head screw | 2 |
## 2. Description
Based on ESP32 control board, we designed a complete kit that includes the required hardware and tools for you to build up a programmable robot arm. In the tutorials we provide, you can control it with a joystick, you can also control it using a mobile phone or a computer connected to the same wifi as our ESP32 board. It can reach out, grab, pick up and move small objects, and it has a memory function to repeat the actions you set.
This is an ideal maker project for beginners to learn the ESP32 board and servo.
## 3. Parameters
Operating voltage: 3.3~5V
DC input voltage: 7~12V
Battery holder: 6-slot AA battery holder / 2-slot 18650 battery holder (Batteries not included)
DOF: 4 degree of freedom
## 4. Features
**Flexibility**: With 4 degrees of freedom, the robot arm is able to move and rotate in multiple directions to perform complex actions and tasks.
**Convenient Control**: The ESP32 microcontroller is used as the control core, and its rich interface are convenient for communication and control with other devices or systems.
**Programming Flexibility**: Automatic operations can be realized via programming, such as planning motion trajectory, grasping and placing objects.
**Openness and Expandability**: The ESP32 platform contains an open ecosystem to be customizes and extended according to needs. You can add sensors and actuators to fit for multiply application.
## 5. KEYESTUDIO ESP32 Main Board

### 5.1 Introduction
Based on ESP-WROOM-32, the keyestudio ESP32 Core board is a mini development board, whose I/O pins are reserved a space of 2.54mm on both sides, so that it can be connected to peripherals according to needs. In addition, these pins also make your operation more concise and convenient when using and debugging.
The ESP-WROOM-32 module adopts industry's leading WiFi + Bluetooth solution. Its external components is fewer than 10, including an antenna switch, RF balun, power amplifier, low noise amplifier, filter and power management module. It also integrates TSMC low-power 40nm technology, featuring high power performance and RF performance. Besides, it is safe, reliable, and easy to expand to various applications.
### 5.2 Parameters
Microcontroller: ESP-WROOM-32 module
USB-to-serial chip: CP2102-GMR
Operating voltage: DC 5V
Operating current: 80mA (average)
Supply current: 500mA (minimum)
Operating voltage: -40°C ~ +85°C
WiFi mode: Station/SoftAP/SoftAP+Station/P2P
WiFi protocol: 802.11 b/g/n/e/i (802.11n, speed up to 150 Mbps)
WiFi frequency range: 2.4 GHz ~ 2.5 GHz
Bluetooth Protocol: BT v4.2 BR/EDR and BLE standard
Dimensions: 55x26x13mm
Weight: 9.3g
### 5.3 Pin-out

Although ESP32 board boasts fewer pins than commonly used processors, you will not encounter any problems when you reuse multiple functions on pins (pins IO36, IO35, IO34, IO39 only inputs signals).
**ATTENTION**: The voltage of ESP32 pins is 3.3V. If it works with other devices with an operating voltage of 5V, a level converter is required.
● **Power**: 2 power supply pins +5V and 3.3V, used to power other devices and modules.

● **GND**: 3 GND pins.
● **Enable pin(EN)**: used to enable or disable modules. The pin enables module at high and disables at low.
● **I/O pin(GPIO)**: 32 GPIO pins, used to communicate with LED, switches, and other input/output devices. These pins can be pulled up or down.
**NOTE: GPIO6 - GPIO11(SCK/CLK, SDO/SD0, SDI/SD1, SHD/SD2,S WP/SD3, SCS/CMD) are used for SPI communication of flash memory inside the module, which are not recommend.**
● **ADC**: 16 ADC pins, used to convert analog voltage(some sensor outputs) to digital voltage. Some of these converters are connected to internal amplifiers so are able to measure small voltages with high accuracy.
● **DAC**: 2 digital-to-analog converters with 8-bit accuracy.
● **Touch pad**: 10 pins that are sensitive to capacitance changes. Touch buttons can be built by connecting these pins to certain pads (pads on the PCB).
● **SPI**: 2 SPI interfaces, used to connect to displays, SD / microSD card, external flash memory, etc.
● **I2C**: Pins SDA and SCL are used for I2C communication.
● **Serial Communication (UART)**: 2 UART serial ports, used to transmit data up to 5Mbps between devices. UART0 also boasts CTS and RTS control function.
● **PWM**: all I/O pins can be used for PWM(pulse width modulation) to control motors, LED brightness and colors, and so on.
### 5.4 Main Parts

## 6. ESP32 Servo Drive Board
### 6.1 Description
The KEYESTUDIO ESP32 servo drive board has 6 servo drive ports (5V), 9 IO ports (3.3V), and two IIC interfaces (3.3V). The servo drive uses two LM2596S-5.0V 3A high current power ICs to provide working voltage to the servo. Then, 1117 3.3V supplies power to 9 IO ports and IIC ports.
### 6.2 Parameters
External power: 7-12V
Servo pin voltage: 5V
IO port voltage: 3.3V
Dimensions: 90 x 55 x 15.5mm
Weight: 41g (bare board)
### 6.3 Pin-out

### 6.4 Schematic Diagram
[Schematic Diagram.PDF](./schematic_diagram.pdf)
## 7. Configure Arduino IDE
### 7.1 Download and install Arduino IDE
You could download the latest Arduino IDE from the official website: https://www.arduino.cc/en/software
There are versions for Windows, Mac, and Linux systems.
Here we will choose the Windows version to show you how to download, install and use it. You can choose between the Installer (.exe) and the Zip packages. We suggest you use the first one that installs directly everything you need to use the Arduino Software (IDE), including the drivers. With the Zip package you need to install the drivers manually. The Zip file is also useful if you want to create a portable installation.
- 1.Select Win 10 and newer, 64 bits in DOWNLOAD OPTIONS.

- 2.Click JUST DOWNLOAD

- 3.Join Newsletter or you can just Click JUST DOWNLOAD

- 4.Save the .exe file downloaded from the software page to your hard drive and simply run the file .

- 5.Read the License Agreement and agree it.

- 6.Choose the installation options.

- 7.Choose the install location.

- 8. In addition, the security center may pop up a few times asking you if you want to install some device driver. Please install all of them.

- 9.Click finish and run Arduino IDE

- 10.Firewall will ask whether we'd like to give allow access, just simply click on Allow access.

- 10.Firewall will ask whether we'd like to give allow access, just simply click on Allow access.
11.Wait for some time to allow arduino IDE to automatically install the Arduino AVR Boards, built-in libraries, and other required files.

---
### 7.2 Introduce of Arduino IDE 2.0

**Verify / Upload** - compile and upload your code to your Arduino Board.
**Select Board & Port** - detected Arduino boards automatically show up here, along with the port number.
**Sketchbook** - here you will find all of your sketches locally stored on your computer. Additionally, you can sync with the Arduino Cloud, and also obtain your sketches from the online environment.
**Boards Manager** - browse through Arduino & third party packages that can be installed. For example, using a MKR WiFi 1010 board requires the Arduino SAMD Boards package installed.
**Library Manager** - browse through thousands of Arduino libraries, made by Arduino & its community.
**Debugger** - test and debug programs in real time.
**Search** - search for keywords in your code.
**Open Serial Monitor** - opens the Serial Monitor tool, as a new tab in the console.
If you want to learn more about Arduino IDE, please refer to this document:[**Getting Started with Arduino IDE 2**](https://docs.arduino.cc/software/ide-v2/tutorials/getting-started-ide-v2/)
---
### 7.3 Install Driver for ESP32 board
The USB-to-serial chip of the ESP32 board is CP2102-GMR.
Connect the ESP32 board to the computer with the usb cable and wait for Windows to begin its driver installation process. Often CP2102 drivers will be automatically installed by your system when using Arduino. You can check the Device Manager or the port of the Arduino IDE to see if the driver is successfully installed.
Open the **Device Manager** by right clicking **“My computer” **and selecting **control panel**.
Look under **Ports (COM & LPT)**. You should see an open port named **Silicon Labs CP210x USB to UART Bridge (COM-X)**
Click **Tools>Port** at Arduino IDE, you can find the com port displayed by device manager

If **the installation process fail**, you should see a device with a tiny yellow triangle and exclamation mark next to it.

**Now let's install CP210x Chip driver manually.**
1. In the tutorial package we downloaded(https://fs.keyestudio.com/FKS0003), you can find the CP210x_6.7.4 driver file.

2. Right click on the **"CP210x USB to UART Bridge Controller"** and choose the **"Update Driver Software"** option.

3. Choose the **"Browse my computer for Driver software"** option.

4. Select the driver file named **"CP210x_6.7.4"**, located in the tutorial package we downloaded.

5. After a while, the driver is installed successfully.

---
### 7.4 Configure the ESP32 environment in Arduino
NOTE: ESP32 environment in Arduino **2.0.12** is recommended, since our tutorials are based on this version. Incompatibilities may exist if other versions are choosed.
--- For Windows, there is an easier way to install the ESP32 environment. Double click the downloaded program `esp32_package_2.0.12_arduinome.exe` in the tutorial package to enable the automatic installation.  Wait for its installation process to complete  You can also find the download link to the `esp32_package_2.0.12_arduinome.exe` : [https://fs.keyestudio.com/ESP32](https://fs.keyestudio.com/ESP32) After the installation is complete, type ESP32 in the BOARDS MANAGER of the Arduino IDE, you will see the the ESP32 environment in Arduino: 2.0.12 (ESP32 by Espressif Systems)  --- ### 7.5 Adjust the servo to 90° before assembly We need to adjust all the servos to 90° before assembly so that the robotic arm will work as preset. Otherwise, the robot will not work and the servos may be burned out. 1. Prepare four servos, an EPS32 board, an ESP32 shield, and a USB cable. | # | PIC | NAME | QTY | | ---- | ------------------------ | ---------------------------------- | ---- | | 1 |  | Keyestudio ESP32 servo drive board | 1 | | 2 |  | keyestudio ESP32 Core board | 1 | | 3 |  | MG90S 14G 180° metal servo | 3 | | 4 |  | 9G 180° servo for robot claw | 1 | | 5 |  | Micro USB cable | 1 | 2.Wiring: | Servo drive board | Servo | | :---------------: | :-------: | | IO17(yellow) | S(yellow) | | 5V(red) | V(red) | | GND(black) | G(brown) |Pay attention to the installation direction of the EPS32 board. Installing it in reverse may burn it.
 3.Connect the ESP32 board to the computer with the USB cable. Select board type **"ESP32 Dev Module"**  4.Select port COM-4 (This depends on the number your computer assigns to the ESP32 board, which you can check in the device manager).   5.Before uploading code, please import “ESP32Servo” library to Arduino IDE to avoid compiling failure.The library file version must be 1.2.1, otherwise an error will also be reported. How to import "ESP32Servo" library:
- [ ] Click the **LIBRARY MANAGER** button in the upper left corner of the Arduino IDE. - [ ] Enter **"ESP32servo"** in the search box. - [ ] Choose the 1.2.1 version of the **"ESP32servo"** library. - [ ] Click to **INTALL** it.  6.Open the code named ***\*Adjust_the_servo_to_90_degrees\**** using the Arduino IDE and upload it.  Or directly copy the code below into the Arduino IDE and click upload. ```c /* Keyestudio ESP32 Robot Arm 7-5 Servo Configuration Function: set servo at pin IO17 to the angle of 90° http://www.keyestudio.com */ #includeNote the pit marked in green as follows:
  NOTE:1.We need to adjust the servo to 90° before assembly. 2.Note the pit marked in green as follows   ### 8.5 Install the base of the turntable Required parts:  Steps:   ### 8.6 Install right-side upper arm and its servo Required parts:  NOTE:We need to adjust the servo to 90° before assembly.   NOTE:1.We need to adjust the servo to 90° before assembly. 2.Note the orientation of the holes marked by the green circles. Vertically mount it as follows: Step1:Fix the servo arm to the acrylic with a M1.2*5 screw Step2:Use a M2*4 screw to mount the acrylic on the servo shaft, taking care to keep the acrylic level with the edge of the servo.   ### 8.7 Install right-side Forearm Required parts:  Steps:     ### 8.8 Install left-side forearm and servo Required parts:  Steps:     NOTE: 1.We need to adjust the servo to 90° before assembly. 2.As marked by the two arrows, the slope of the forearm should be aligh with the carved line on the upper arm.   ### 8.9 Install the robot's elbow and servo Required parts:  Steps:   ### 8.10 Install Claw Required parts:  NOTE: 1.We need to adjust the servo to 90° before assembly. 2.When assembling the gear and clip, do not turn the servo shaft to avoid changing its already adjusted 90° position.       ### 8.11 Install the arm Required parts:  Steps: ①②③④     ### 8.12 Intall the arm to the base Required parts:  Steps:      NOTE: 1.We need to adjust the servo to 90° before assembly. 2.Note the pit marked in green as follows   ### 8.13 Fixing the robot arm to the robot base   ### 8.14 Install Joystick Required parts:  Steps:     ### 8.15 Wiring Servo wiring: Connect the corresponding servo motor to the corresponding IO port according to the schematic diagram of the image(The wiring is consistent with the angle settings of each servo motor)  Attention: The servo of the claw part requires a longer wiring, so a 3-pin DuPont cable is used for connection
 Joystick wiring: | Servo drive board | Left joystick module | | :---------------: | :------------------: | | 5V(red) | V | | GND(black) | G | | IO12(yellow) | B | | IO13(yellow) | X | | IO15(yellow) | Y | | Servo drive board | Right joystick module | | :---------------: | :-------------------: | | 5V(red) | V | | GND(black) | G | | IO25(yellow) | B | | IO33(yellow) | X | | IO32(yellow) | Y |  ## 9. Robot Arm Projects ### 9.1 Control the turntable of the robotic arm **9.1.1 Introduction** Servo is a position driver, which is mainly composed of a shell, a circuit board, a non-core motor, a gear and a position detector. When a receiver or an MCU sends a signal to the steering gear, its built-in reference circuit generates a reference signal with a period of 20ms and a width of 1.5ms. The obtained DC bias voltage will be compared with the voltage of the potentiometer to output a voltage difference. There are many specifications of the servo, and generally most of them conclude three external wires in brown(grounded), red(power positive), orange(signal), Yet the colors may vary from brands.  **9.1.2 Parameters** Operating voltage: DC 4.8V 〜 6V Dimensions: 32.2 x 12 x 33.3mm Torque: 2.0kg (4.8v) Speed: 0.11s (4.8v) Rotation angle: Maximum 180° Pulse width range: 500→2500 μsec Servo type: Analog servo Operating temperature: 0°-55° Dead-time: 5 microseconds Structure material: metal copper gear, hollow cup motor, double ball bearing **9.1.3 Principle** The rotation angle of the servo can be controlled by adjusting the duty cycle of the PWM (pulse width modulation) signal. The period of the standard PWM (pulse width modulation) signal is fixed at 20ms (50Hz). Theoretically, pulse width should be within 1ms ~ 2ms, but in fact, the range is 0.5ms ~ 2.5ms, corresponding to the rotation angle of 0° to 180°.  Corresponding servo Angle value:  **9.1.4 Wiring Diagram** In the previous assembly steps, we connected the **servo where the turntable is located** to the IO16.External power supply is required, because the current of the development board is far from meeting the relatively large current requirements for driving the servo.
 **9.1.5 Upload Code** Before uploading code, please import “ESP32Servo” library to Arduino IDE to avoid compiling failure.The library file version must be 1.2.1, otherwise an error will also be reported. How to import "ESP32Servo" library:
- [ ] Click the **LIBRARY MANAGER** button in the upper left corner of the Arduino IDE. - [ ] Enter **"ESP32servo"** in the search box. - [ ] Choose the 1.2.1 version of the **"ESP32servo"** library. - [ ] Click to **INTALL** it.  Use the Arduino IDE to open this code directly from the tutorial package. Connect the ESP32 board to the computer with the USB cable. Select board type "ESP32 Dev Module" and select port COM-XX (This depends on the number your computer assigns to the ESP32 board, which you can check it in the device manager).  Or you can copy and paste the code from below into the Arduino IDE. ```c /* Keyestudio ESP32 Robot Arm 9-1 tutorial code Function: control the servo to rotate to 0°, 90°, 180° http://www.keyestudio.com */ #includeThe library file version must be 1.2.1, otherwise an error will also be reported. How to import "ESP32Servo" library:
Use the Arduino IDE to open this code directly from the tutorial package. Connect the ESP32 board to the computer with the USB cable. Select board type "ESP32 Dev Module" and select port COM-XX (This depends on the number your computer assigns to the ESP32 board, which you can check it in the device manager).  Or copy the code below into the Arduino IDE and click upload. ```c /* Keyestudio ESP32 Robot Arm 9-2 tutorial code Function: http://www.keyestudio.com */ //Define the left remote rod pin #define left_B 12 #define left_X 13 #define left_Y 15 //Define the right remote rod pin #define right_B 25 #define right_X 33 #define right_Y 32 //Define variables for storing remote sensing values int left_B_data, left_Y_data, left_X_data, right_B_data, right_X_data, right_Y_data; void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(left_B, INPUT); //Set pins to input mode pinMode(left_X, INPUT); pinMode(left_Y, INPUT); pinMode(right_B, INPUT); pinMode(right_X, INPUT); pinMode(right_Y, INPUT); } void loop() { // put your main code here, to run repeatedly: left_B_data = digitalRead(left_B); left_X_data = analogRead(left_X); left_Y_data = analogRead(left_Y); right_B_data = digitalRead(right_B); right_X_data = analogRead(right_X); right_Y_data = analogRead(right_Y); Serial.print(" left B:"); Serial.print(left_B_data); Serial.print(" left X:"); Serial.print(left_X_data); Serial.print(" left Y:"); Serial.println(left_Y_data); Serial.print("right B:"); Serial.print(right_B_data); Serial.print(" right X:"); Serial.print(right_X_data); Serial.print(" right Y:"); Serial.println(right_Y_data); delay(300); } ``` Result After uploading the code, open the **serial port monitor** and set the serial port baud rate to **9600**, you will see the printed remote control value on it. If you feel that the serial port printing speed is too fast, you can increase the value in the parentheses of the delay ().  ### 9.3 Joystick Control Robot Arm 9.3.1 Introduction We connect the ESP32 development board and the joystick module to the servo drive board, and then the development board reads the value of the axis X/Y of the module to determine the rotation angle, so that the arm is controlled by the module. 9.3.2 Flow  #### 9.3.3 Control the robot with the joystick. Use the Arduino IDE to open this code directly from the tutorial package.  Or you can copy and paste the code from below into the Arduino IDE. ```c /* Keyestudio ESP32 Robot Arm 9-3-3 tutorial code Function: joystick control the robot arm http://www.keyestudio.com */ #include "ESP32Servo.h" Servo base; // create servo object to control a servo Servo arm; Servo forearm; Servo gripper; //set servo control pins #define basePin 16 #define armPin 17 #define forearmPin 2 #define gripperPin 4 //set left joystick pins #define left_B 12 #define left_X 13 #define left_Y 15 //set right joystick pins #define right_B 25 #define right_X 33 #define right_Y 32 int left_B_data, left_Y_data, left_X_data, right_B_data, right_X_data, right_Y_data; //servo int baseAngle = 90; // Initialize bottom servo angle int armAngle = 90; // Initialize upper arm servo angle int forearmAngle = 90; // Initialize forearm servo angle int gripperAngle = 90; // Initialize claw servo angle void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(left_B, INPUT); pinMode(left_X, INPUT); pinMode(left_Y, INPUT); pinMode(right_B, INPUT); pinMode(right_X, INPUT); pinMode(right_Y, INPUT); base.attach(basePin); // attaches the servo on pin 16 to the servo object arm.attach(armPin); forearm.attach(forearmPin); gripper.attach(gripperPin); base.write(baseAngle); arm.write(armAngle); forearm.write(forearmAngle); gripper.write(gripperAngle); } void loop() { // put your main code here, to run repeatedly: left_B_data = digitalRead(left_B); left_X_data = analogRead(left_X); left_Y_data = analogRead(left_Y); right_B_data = digitalRead(right_B); right_X_data = analogRead(right_X); right_Y_data = analogRead(right_Y); baseControl(); armControl(); forearmControl(); gripperControl(); } //control base void baseControl() { if (left_X_data > 3000) { while (analogRead(left_X) > 3000) { base.write(baseAngle++); if (baseAngle >= 180) baseAngle = 180; delay(10); } } else if (left_X_data < 20) { while (analogRead(left_X) < 20) { base.write(baseAngle--); if (baseAngle <= 0) baseAngle = 0; delay(10); } } } //control upper arm void armControl() { if (left_Y_data > 3000) { while (analogRead(left_Y) > 3000) { arm.write(armAngle++); if (armAngle >= 180) armAngle = 180; delay(10); } } else if (left_Y_data < 20) { while (analogRead(left_Y) < 20) { arm.write(armAngle--); if (armAngle <= 80) armAngle = 80; delay(10); } } } //control forearm void forearmControl() { if (right_Y_data < 20) { while (analogRead(right_Y) < 20) { forearm.write(forearmAngle++); if (forearmAngle >= 120) forearmAngle = 120; delay(10); } } else if (right_Y_data > 3000) { while (analogRead(right_Y) > 3000) { forearm.write(forearmAngle--); if (forearmAngle <= 30) forearmAngle = 30; delay(10); } } } //control claw void gripperControl() { if (right_X_data > 3000) { while (analogRead(right_X) > 3000) { gripper.write(gripperAngle++); if (gripperAngle >= 150) gripperAngle = 150; delay(10); // gripper.write(180); } } else if (right_X_data < 20) { while (analogRead(right_X) < 20) { // gripper.write(80); gripper.write(gripperAngle--); if (gripperAngle <= 90) gripperAngle = 90; delay(10); } } } ``` 9.3.4 Test Result After uploading the code, rotate joysticks to control the arm. For the left joystick, axis X controls the entire rotation of the robot arm (X < 20: turn right; X > 3000: turn left); its axis Y raises and lowers the upper arm (Y < 20: up; Y > 3000: down). For the right joystick, axis X controls the claw (X < 20: splay; X > 3000: clench); axis Y raises and lowers the forearm (Y < 20: up; Y > 3000: down). Push up the joystick module to raise up axis Y, so its value decreases, and push down to increase the value of axis Y. The working principle of the upper arm and the forearm are alike.   #### 9.3.5 Remember and repeat the action The current angle of the servo can be stored continuously for 10 times by pressing the button on the right joystick, and the action playback can be performed when we press the button on the left joystick. 9.3.5.1 Flow  9.3.5.2 Code Use the Arduino IDE to open this code directly from the tutorial package. Connect the ESP32 board to the computer with the USB cable. Select board type "ESP32 Dev Module" and select port COM-XX (This depends on the number your computer assigns to the ESP32 board, which you can check it in the device manager).  Or you can copy and paste the code from below into the Arduino IDE. ```c /* Keyestudio ESP32 Robot Arm 9-3-5 tutorial code Function: joystick controls arm, axis z stores the rotation angle and re-plays the action http://www.keyestudio.com */ #include "ESP32Servo.h" Servo base; // create servo object to control a servo Servo arm; Servo forearm; Servo gripper; //Define servo control pin #define basePin 16 #define armPin 17 #define forearmPin 2 #define gripperPin 4 //Define left joystick pin #define left_B 12 #define left_X 13 #define left_Y 15 //Define right joystick pin #define right_B 25 #define right_X 33 #define right_Y 32 int left_B_data, left_Y_data, left_X_data, right_B_data, right_X_data, right_Y_data; //servo int baseAngle = 90; // initialize base servo angle int armAngle = 90; // initialize upper arm servo angle int forearmAngle = 90; // initialize forearm servo angle int gripperAngle = 90; // initialize claw servo angle int attitude_data[4][11]; int base_attitude = 0; int arm_attitude = 1; int forearm_attitude = 2; int gripper_attitude = 3; int data_start_bit = 1; int data_end_bit = 0; void setup() { // put your setup code here, to run once: pinMode(left_B, INPUT); pinMode(left_X, INPUT); pinMode(left_Y, INPUT); pinMode(right_B, INPUT); pinMode(right_X, INPUT); pinMode(right_Y, INPUT); Serial.begin(9600); base.attach(basePin); // attaches the servo on pin 16 to the servo object arm.attach(armPin); forearm.attach(forearmPin); gripper.attach(gripperPin); base.write(90); arm.write(90); forearm.write(90); gripper.write(90); } void loop() { // put your main code here, to run repeatedly: left_B_data = digitalRead(left_B); left_X_data = analogRead(left_X); left_Y_data = analogRead(left_Y); right_B_data = digitalRead(right_B); right_X_data = analogRead(right_X); right_Y_data = analogRead(right_Y); attitude(); baseControl(); armControl(); forearmControl(); gripperControl(); } //base control void baseControl() { if (left_X_data > 3000) { while (analogRead(left_X) > 3000) { base.write(baseAngle++); if (baseAngle >= 180) baseAngle = 180; delay(10); } } else if (left_X_data < 20) { while (analogRead(left_X) < 20) { base.write(baseAngle--); if (baseAngle <= 0) baseAngle = 0; delay(10); } } } //upper arm control void armControl() { if (left_Y_data > 3000) { while (analogRead(left_Y) > 3000) { arm.write(armAngle++); if (armAngle >= 180) armAngle = 180; delay(10); } } else if (left_Y_data < 20) { while (analogRead(left_Y) < 20) { arm.write(armAngle--); if (armAngle <= 80) armAngle = 80; delay(10); } } } //forearm control void forearmControl() { if (right_Y_data < 30) { while (analogRead(right_Y) < 30) { forearm.write(forearmAngle++); if (forearmAngle >= 150) forearmAngle = 150; delay(10); } } else if (right_Y_data > 3000) { while (analogRead(right_Y) > 3000) { forearm.write(forearmAngle--); if (forearmAngle <= 30) forearmAngle = 30; delay(10); } } } //claw control void gripperControl() { if (right_X_data > 3000) { while (analogRead(right_X) > 3000) { gripper.write(gripperAngle++); if (gripperAngle >= 150) gripperAngle = 150; delay(10); // gripper.write(180); } } else if (right_X_data < 20) { while (analogRead(right_X) < 20) { // gripper.write(80); gripper.write(gripperAngle--); if (gripperAngle <= 90) gripperAngle = 90; delay(10); } } } void attitude() { if (right_B_data == 1) { delay(10); //eliminate button jitters if (right_B_data == 1) { attitude_data[base_attitude][data_start_bit] = base.read(); delay(100); attitude_data[arm_attitude][data_start_bit] = arm.read(); delay(100); attitude_data[forearm_attitude][data_start_bit] = forearm.read(); delay(100); attitude_data[gripper_attitude][data_start_bit] = gripper.read(); delay(100); data_start_bit++; data_end_bit = data_start_bit; if (data_start_bit > 10) data_start_bit = 10; } } if (left_B_data == 1) { delay(10); if (left_B_data == 1) { data_start_bit = 1; baseAngle = base.read(); armAngle = arm.read(); forearmAngle = forearm.read(); gripperAngle = gripper.read(); for (int i = 1; i < data_end_bit; i++) { //base if (baseAngle < attitude_data[base_attitude][i]) { while (baseAngle < attitude_data[base_attitude][i]) { base.write(baseAngle); delay(10); baseAngle++; } } else { while (baseAngle > attitude_data[base_attitude][i]) { base.write(baseAngle); delay(10); baseAngle--; } } //upper arm if (armAngle < attitude_data[arm_attitude][i]) { while (armAngle < attitude_data[arm_attitude][i]) { arm.write(armAngle); delay(10); armAngle++; } } else { while (armAngle > attitude_data[arm_attitude][i]) { arm.write(armAngle); delay(10); armAngle--; } } //forearm if (forearmAngle < attitude_data[forearm_attitude][i]) { while (forearmAngle < attitude_data[forearm_attitude][i]) { forearm.write(forearmAngle); delay(10); forearmAngle++; } } else { while (forearmAngle > attitude_data[forearm_attitude][i]) { forearm.write(forearmAngle); delay(10); forearmAngle--; } } //claw if (gripperAngle < attitude_data[gripper_attitude][i]) { while (gripperAngle < attitude_data[gripper_attitude][i]) { gripper.write(gripperAngle); delay(10); gripperAngle++; } } else { while (gripperAngle > attitude_data[gripper_attitude][i]) { gripper.write(gripperAngle); delay(10); gripperAngle--; } } } //for end } } } ``` 9.3.5.3 Result Every time you press the right joystick in the direction of acrylic, you can record an action, we can record up to 10 actions, after recording the action, press the left joystick in the direction of acrylic, the robot starts to execute the action just recorded.  ### 9.4 WiFi Control Robot Arm #### 9.4.1 Introduction In this experiment, we will control the arm through WiFi. **You need to prepare:** - a **2.4 GHz WiFi**. It can be a mobile hotspot or a router. - a phone/IPAD/computer that can connect to the same internet. - The network name and password of your wifi. NOTE: In the all codes we provided for ESP32 control, you need to change the word **your_SSID** in the code to your WiFi name and **your_PASSWORD** in the code to your WiFi password before uploading.  #### 9.4.2 Connect the ESP32 board to WiFi ESP32 Development Board comes with built-in Wi-Fi (2.4G) and Bluetooth (4.2) capabilities to easily connect to a Wi-Fi network and communicate with other devices in the network. You can use ESP32 to build web pages and display them in a browser. **Arduino IDE includes a library \In this project, some extracurricular knowledge are involved such as HTML, CSS and JS. Here is only a brief introduction. For detailed theories, please google them by yourself.
9.4.3.1 Flow  9.4.4.2 Code Use the Arduino IDE to open this code directly from the tutorial package. Connect the ESP32 board to the computer with the USB cable. Select board type "ESP32 Dev Module" and select port COM-XX (This depends on the number your computer assigns to the ESP32 board, which you can check it in the device manager).  Or you can copy and paste the code from below into the Arduino IDE. Modify **your_SSID** and **your_PASSWORD** into your own wifi name and passwords: ```c++ const char *SSID = "your_SSID"; const char *PASS = "your_PASSWORD"; ``` Code: ```c /* Keyestudio ESP32 Robot Arm 10-4-3-2 tutorial code Function: connect ESP32 to wifi to check IP address. Visit the address to enter a control panel to control the arm wirelessly http://www.keyestudio.com */ #include